Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Fixed BeanPostProcessor detection. #9

Closed
wants to merge 1 commit into from
Closed

Fixed BeanPostProcessor detection. #9

wants to merge 1 commit into from

Conversation

hekonsek
Copy link
Contributor

Hi,

While playing around with FunctionalConfiguration I've discovered that BeanPostProcessor instances registered in the context via bean() DSL method do not processes the beans as they ought to.

The minimal example of such broken configuration is demonstrated below.

class ConfigWithBeanPostProcessor extends FunctionalConfiguration {

  bean()(new AutowiredAnnotationBeanPostProcessor)

  bean()("autowireMe")

  bean()(new AutowireSubject)

}

class AutowireSubject {

  @Autowired
  var autowiredMember : String = _

}

What we expect here is that String will be injected into the AutowireSubject as autowiredMember. Unfortunately it is not true.

I couldn't resist the temptation and investigated this problem a little bit. The issue is that FunctionalConfiguration#bean method registers the Function0Wrapper instance which is responsible for creating the actual BeanPostProcessor object. However AbstractBeanFactory#isFactoryBean method cannot recognize that Function0Wrapper#apply method returns BeanPostProcessor instance because the return type of the latter method is parameterized as <T> (i.e. returns Object for the reflection API).

I definitely don't feel like Spring internals expert, but the solution that seems reasonable for me is to recognize on the FunctionalGenericBeanDefinition level if the wrapped function returns BeanPostProcessor. If so, then FunctionalGenericBeanDefinition should be created with the special version of Function0Wrapper#apply method called (let's say) Function0Wrapper#applyAsBeanPostProcessor. The latter factory method would wrap Function0<BeanPostProcessor> instances and explicitly define BeanPostProcessor return type. If Function0Wrapper factory method defined on FunctionalGenericBeanDefinition has return type of BeanPostProcessor, then AbstractBeanFactory#isFactoryBean works like a charm. And AbstractBeanFactory#isFactoryBean method working properly resolves the issue, as AbstractApplicationContext#registerBeanPostProcessors can recognize that instance return by Function0Wrapper is a BeanPostProcessor.

The pull request contains both fix and test case for it.

Best regards.

@poutsma
Copy link

poutsma commented Feb 26, 2013

Unfortunately, BeanPostProcessors aren't the only kind of beans to require special treatment by the bean factory, other interfaces need eager instantiation as well. The problem here is that we know the target type in Scala (through the Manifest), but there is no way to specify it in the BeanDefinition. I've asked @jhoeller to add a field to the RootBeanDefinition where we can provide this information. See https://jira.springsource.org/browse/SPR-10335.

@hekonsek
Copy link
Contributor Author

Definitely the modification in Spring Core would be the best way to go. The question however is when issue you raised [1] will be resolved. If Spring Scala users would have to wait for it, then it will be best to introduce the workaround like the one proposed (or the better one). After the change you requested will be introduced to Spring Core and released, you could replace workaround with the proper solution.

BeanPostProcessors not working properly is something that will very fast hit people playing with Spring Scala. This could leave bad impression regarding the project.

I would say +1 for temporary workaround (not necessarily the one authored by me).

[1] https://jira.springsource.org/browse/SPR-10335

@jhoeller
Copy link

We intend to roll that change into Spring Framework 3.2.2, scheduled for next week. The next Spring Scala release can immediately build on it.

@hekonsek
Copy link
Contributor Author

Hi Juergen,

I'm glad to hear that we are talking about the next week. I therefore propose to close this pull request, as there is nothing here to be merged anymore. From this point forward we could track the issue on Jira [1] instead.

BTW are there any plans regarding the release of the next milestone of Spring Scala? I'm advocate of Scala in our Apache Camel [2] community and would like to make Spring Scala configuration the 1st class citizen there. This would make deployment of Scala modules to ServiceMix [3] easier and definitely more elegant.

[1] https://jira.springsource.org/browse/SCALA-7
[2] http://camel.apache.org
[3] http://servicemix.apache.org

@hekonsek hekonsek closed this Feb 26, 2013
@poutsma
Copy link

poutsma commented Feb 27, 2013

The main holdback for release a second milestone is the lack of JdbcTemplate. We currently have a SimpleJdbcTemplate, but since the original Java version of that has been deprecated, we need to come up with a replacement (in the form of a JdbcTemplate and a NamedParameterJdbcTemplate) and remove the SimpleJdbcTemplate. Various members of the community have said to be working on one, but so far nothing has come up. Perhaps I need to do it myself. Or perhaps you feel like giving it a shot, @hekonsek? Ping me if you need more information.

@hekonsek
Copy link
Contributor Author

Sure, I can handle the JDBC template stuff. If this could push Spring Scala release forward, I would be happy to help. Could you create the Jira ticket for this issue and send me link on [email protected] ?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants